/*
 * G3DMExporter.cpp
 *
 *  Created on: Jan 13, 2014
 *      Author: knuke
 */

#include "G3DMExporter.h"
#include "Model.h"
#include "BinaryStream.h"
#include "Types.h"
#include "Material.h"
#include "Triangle.h"
#include "Mesh.h"
#include "Node.h"
#include <string>
#include <fstream>
#include <iostream>

using std::string;
using std::ofstream;
using std::cout;
using std::endl;

namespace graphiclicious_converter
{

  G3DMExporter::G3DMExporter()
  {
  }

  G3DMExporter::~G3DMExporter()
  {
  }

  void G3DMExporter::exportModel(Model* model, string out_file)
  {
    stream_.open(out_file, false);

    uint mat_cnt = model->materials_.size();
    stream_.writeInt(mat_cnt);  // Material Count

    COUNTER_LOOP(mat_idx, 0, mat_cnt)
      writeMaterial(model->materials_[mat_idx]);

    uint mesh_cnt = model->meshes_.size();
    stream_.writeInt(mesh_cnt);  // Mesh Count

    COUNTER_LOOP(mesh_idx, 0, mesh_cnt)
      writeMesh(model->meshes_[mesh_idx]);

    writeNode(model->root_node_);

    cout << "Scene exported successfully." << endl;

    stream_.flush();
  }

  void G3DMExporter::writeMaterial(Material* mat)
  {
    stream_.writeFloats(&(mat->ambient_[0]), 4);  // Ambient
    stream_.writeFloats(&(mat->diffuse_[0]), 4);  // Diffuse
  }

  void G3DMExporter::writeMesh(Mesh* mesh)
  {
    uint tri_cnt = mesh->triangles_.size();
    stream_.writeInt(tri_cnt);  // Triangle Count
    COUNTER_LOOP(tri_idx, 0, tri_cnt)
      writeTriangle(mesh->triangles_[tri_idx]);
    stream_.writeInt(mesh->material_);  // Material ID
  }

  void G3DMExporter::writeTriangle(Triangle* tri)
  {
    stream_.writeFloats(&(tri->v1_[0]), 3);  // Vertex 1
    stream_.writeFloats(&(tri->v2_[0]), 3);  // Vertex 2
    stream_.writeFloats(&(tri->v3_[0]), 3);  // Vertex 3
  }

  void G3DMExporter::writeNode(Node* node)
  {
    uint mesh_cnt = node->meshes_.size();
    stream_.writeInt(mesh_cnt); // Mesh Count

    COUNTER_LOOP(mesh_idx, 0, mesh_cnt)
      stream_.writeInt(node->meshes_[mesh_idx]);  // Mesh ID

    uint child_cnt = node->children_.size();
    stream_.writeInt(child_cnt);  // Child Count

    COUNTER_LOOP(child_idx, 0, child_cnt)
      writeNode(node->children_[child_idx]);
  }

} /* namespace graphiclicious_converter */
